<template>
  <div>
    <p v-if="isShaking">摇一摇中...</p>
    <p v-else>请摇晃手机,需要在https环境</p>
    <button @click="shake()">打开shake</button>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { showConfirmDialog, showToast } from 'vant'

const isShaking = ref(false)

let lastX: number,
  lastY: number,
  lastZ: number,
  lastUpdate = 0

const shake1 = () => {
  if (typeof (DeviceMotionEvent as any).requestPermission === 'function') {
    ;(DeviceMotionEvent as any)
      .requestPermission()
      .then((permissionState: string) => {
        if (permissionState === 'granted') {
          console.log('已授权访问运动传感器')
        } else {
          showToast('未授权访问运动传感器,请手动点击抽奖')
        }
      })
      .catch(() => {
        showToast('未授权访问运动传感器,请手动点击抽奖！')
      })

    useEventListener(window, 'devicemotion', handleShake)
  }
}
const requestDeviceMotionPermission = () => {
  return (DeviceMotionEvent as any)
    .requestPermission()
    .then((permissionState: string) => {
      if (permissionState === 'granted') {
        return true
      } else {
        return false
      }
    })
    .catch(() => {
      return false
    })
}
const shake = async () => {
  if (typeof (DeviceMotionEvent as any).requestPermission === 'function') {
    const isPermissionGranted = await requestDeviceMotionPermission()
    if (isPermissionGranted) {
      useEventListener(window, 'devicemotion', handleShake)
    } else {
      showToast('未授权访问运动传感器,请手动点击抽奖！')
    }
  } else {
    useEventListener(window, 'devicemotion', handleShake)
  }
}

function handleShake(event: DeviceMotionEvent) {
  const acceleration = event.accelerationIncludingGravity || {
    x: 0,
    y: 0,
    z: 0,
  }
  const currTime = Date.now()
  if (currTime - lastUpdate > 100) {
    const diffTime = currTime - lastUpdate
    lastUpdate = currTime

    const x = acceleration.x || 0
    const y = acceleration.y || 0
    const z = acceleration.z || 0

    const speed =
      (Math.abs(x + y + z - lastX - lastY - lastZ) / diffTime) * 10000

    if (speed > 2000) {
      isShaking.value = true
      setTimeout(() => {
        isShaking.value = false
      }, 10000)
    }

    lastX = x
    lastY = y
    lastZ = z
  }
}
</script>
